package com.kds.smarthome.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.kds.smarthome.annotation.BuildingCode;
import com.kds.smarthome.annotation.DateRange;
import com.kds.smarthome.annotation.Log;
import com.kds.smarthome.common.AjaxResponse;
import com.kds.smarthome.common.DateType;
import com.kds.smarthome.common.EnergyType;
import com.kds.smarthome.common.EnergyValue;
import com.kds.smarthome.controller.vo.*;
import com.kds.smarthome.entity.Building;
import com.kds.smarthome.security.jwt.TokenProvider;
import com.kds.smarthome.service.BuildingService;
import com.kds.smarthome.service.EnergyService;
import com.kds.smarthome.service.MongoAggregationQuery;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 孔德嵩
 * 创建日期 2024/12/13
 */
@Slf4j
@RestController
@RequestMapping("/api/energy")
public class EnergyController {

    @Autowired
    private EnergyService energyService;

    @Autowired
    private BuildingService buildingService;

    @Autowired
    private TokenProvider tokenProvider;

    @Autowired
    private EnergySVGController svgController;

    @Autowired
    private MongoAggregationQuery query;

    /**
     * @param buildingCode
     * @param token
     * @return
     */
    @Log(title = "能源统计卡片概览", businessType = 0)
    @GetMapping("/overview/energyStatsCard")
    public AjaxResponse<List<EnergyStatsCard>> overview(@BuildingCode String buildingCode, @RequestHeader("Authorization") String token) {


        Building currentBuilding = tokenProvider.getCurrentBuilding(token, buildingCode);
        if (currentBuilding == null) {
            return AjaxResponse.error("未找到指定建筑");
        }

        DateTime now = new DateTime();

        List<EnergyStatsCard> rs = new ArrayList<>();
        for (EnergyType energyType : currentBuilding.getEnergyTypes()) {
            EnergyStatsCard energyStatsCard = energyService.energyStatsCard(currentBuilding.getCode(),energyType, now);
            rs.add(energyStatsCard);
        }

        return AjaxResponse.success(rs);
    }


    /**
     * 能源管理-能耗分析
     *
     * @param buildingCode 建筑编码
     * @param energyType 能源类型
     * @param dateObject 对象
     * @return 能源数据列表
     */
    @Log(title = "能耗分析", businessType = 0)
    @GetMapping("/overview/analysis/{energyType}")
    public AjaxResponse<List<? extends EnergyValue>> overviewAnalysis(
            @BuildingCode String buildingCode,
            @PathVariable EnergyType energyType,
            @DateRange DateObject dateObject) {

        log.info("energyType:{}, startTime:{}, endTime:{}", energyType,
            JSON.toJSONString(dateObject.getStartTime(), SerializerFeature.UseISO8601DateFormat),
            JSON.toJSONString(dateObject.getEndTime(), SerializerFeature.UseISO8601DateFormat));

        try {
            List<? extends EnergyValue> rs = energyService.queryByEnergyType(
                buildingCode,
                energyType,
                dateObject.getType(),
                dateObject.getStartTime(),
                dateObject.getEndTime()
            );

            return AjaxResponse.success(rs);
        } catch (RuntimeException e) {
            return AjaxResponse.error(e.getMessage());
        }
    }

    @Log(title = "多表计数据查询", businessType = 0)
    @GetMapping("/meter/multiquery")
    public AjaxResponse<List<MeterData>> queryMultiMeterData(
            @BuildingCode String buildingCode,
            @RequestParam List<String> fids,
            @RequestParam("dateType") DateType type,
            @DateRange List<DateObject> dateObjects,
            @RequestHeader("Authorization") String token) {

        try {
            Building currentBuilding = tokenProvider.getCurrentBuilding(token, buildingCode);
            if (currentBuilding == null) {
                return AjaxResponse.error("未找到指定建筑");
            }


            List<MeterData> result =query.metersMultiDatesQuery(fids,type,dateObjects);

            return AjaxResponse.success(result);
        } catch (RuntimeException e) {
            log.error("Error querying multi meter data", e);
            return AjaxResponse.error(e.getMessage());
        }
    }

    private List<Date> parseDates(String dateValues) {
        return Arrays.stream(dateValues.split(","))
            .map(dateStr -> {
                try {
                    return new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
                } catch (ParseException e) {
                    throw new IllegalArgumentException("Invalid date format: " + dateStr);
                }
            })
            .collect(Collectors.toList());
    }

    private List<EnergyValue> generateDataPoints(DateType dateType) {
        List<EnergyValue> points = new ArrayList<>();
        int count;

        switch (dateType) {
            case DAY:
                count = 24;     // 24小时
                break;
            case MONTH:
                count = 31;     // 最多31天
                break;
            case YEAR:
                count = 12;     // 12个月
                break;
            default:
                throw new IllegalArgumentException("Unsupported date type: " + dateType);
        }

        Random random = new Random();
        for (int i = 0; i < count; i++) {
            EnergyValue point = new EnergyValue();
            point.setIndex(i);
            point.setValue(random.nextDouble() * 100); // 生成0-100的随机数
            points.add(point);
        }

        return points;
    }

    /**
     * 平均面积能耗评估
     */
    @Log(title = "平均面积能耗评估", businessType = 0)
    @GetMapping("/assess/averageArea")
    public AjaxResponse<AssessResult> assessAverageArea(
            @BuildingCode String buildingCode,
            @RequestHeader("Authorization") String token) {

        try {
            Building currentBuilding = tokenProvider.getCurrentBuilding(token, buildingCode);
            if (currentBuilding == null) {
                return AjaxResponse.error("未找到指定建筑");
            }

            // 计算平均面积能耗
            double value = energyService.calculateAverageArea(buildingCode);
            log.debug("Calculated average area energy consumption: {} for building: {}",
                value, buildingCode);

            // 生成SVG图形
            String svgData = svgController.generateAvgAreaEnergyRuler(value, 500, 100)
                .getBody();  // 从ResponseEntity中获取body

            return AjaxResponse.success(new AssessResult(value, svgData));
        } catch (Exception e) {
            log.error("Error assessing average area", e);
            return AjaxResponse.error(e.getMessage());
        }
    }

    /**
     * 能效比评估
     */
    @Log(title = "能效比评估", businessType = 0)
    @GetMapping("/assess/eer")
    public AjaxResponse<AssessResult> assessEER(
            @BuildingCode String buildingCode,
            @RequestHeader("Authorization") String token) {

        try {
            Building currentBuilding = tokenProvider.getCurrentBuilding(token, buildingCode);
            if (currentBuilding == null) {
                return AjaxResponse.error("未找到指定建筑");
            }

            // 计算能效比
            double value = energyService.calculateEER(buildingCode);
            log.debug("Calculated EER: {} for building: {}", value, buildingCode);

            // 生成SVG图形
            String svgData = svgController.getEERRuler(value,500, 100)
                .getBody();  // 从ResponseEntity中获取body

            return AjaxResponse.success(new AssessResult(value, svgData));
        } catch (Exception e) {
            log.error("Error assessing EER", e);
            return AjaxResponse.error(e.getMessage());
        }
    }

    @Log(title = "能源流量数据", businessType = 0)
    @GetMapping("/assess/energyflow")
    public AjaxResponse<EnergyFlowData> energyflow(
            @BuildingCode String buildingCode,
            @RequestHeader("Authorization") String token) {

        try {
            Building currentBuilding = tokenProvider.getCurrentBuilding(token, buildingCode);
            if (currentBuilding == null) {
                return AjaxResponse.error("未找到指定建筑");
            }

            log.debug("Query energy flow data for building: {}", buildingCode);

            EnergyFlowData flowData = energyService.getEnergyFlow(buildingCode);

            return AjaxResponse.success(flowData);
        } catch (RuntimeException e) {
            log.error("Error querying energy flow data", e);
            return AjaxResponse.error(e.getMessage());
        }
    }

}
